using FireStarterModeller.BO;
using FireStarterModeller.Logic.Commands;
using FireStarterModeller.Test.BO;
using Habanero.Base.Exceptions;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.Logic.Commands
{
    [TestFixture]
    public class TestCreateClassCommand
    {

        [TestFixtureSetUp]
        public void SetupFixture()
        {
            TestUtilsLogic.SetupFixture();
        }
        [SetUp]
        public void SetupTest()
        {
            TestUtilsLogic.SetupTest();
        }

        //Create class (using current assembly)
        [Test]
        public void Test_Apply()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            const string className = "Class1";
            ICommandFactory commandFactory = new CommandFactory();
            DMAssembly assembly = dmSolution.DefaultAssembly;

            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dmSolution.AllClasses.Count);

            //---------------Execute Test ----------------------
            ICommand command = commandFactory.CreateCreateClass(assembly, className);
            command.Apply();

            //---------------Test Result -----------------------
            Assert.AreEqual(1, dmSolution.AllClasses.Count);
            DMClass dmClass = dmSolution.AllClasses[0];
            Assert.IsFalse(dmClass.Status.IsNew);
            Assert.AreEqual(className, dmClass.ClassNameBO);
            Assert.AreSame(assembly, dmClass.Assembly);
        }

        //Create class (using current assembly)
        [Test]
        public void Test_Apply_Failure()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            const string className = "Class1";
            ICommandFactory commandFactory = new CommandFactory();
            DMAssembly assembly = dmSolution.DefaultAssembly;
            commandFactory.CreateCreateClass(assembly, className).Apply();

            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmSolution.AllClasses.Count);

            //---------------Execute Test ----------------------
            try
            {
                ICommand command = commandFactory.CreateCreateClass(assembly, className);
                command.Apply();
                Assert.Fail("Expect error due to duplicate class name in assembly");
            } catch (BusObjDuplicateConcurrencyControlException)
            {
                Assert.AreEqual(1, dmSolution.AllClasses.Count);
            }
        }

        [Test]
        public void Test_Revert()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            string className = TestUtilsShared.GetRandomString();
            ICommandFactory commandFactory = new CommandFactory();
            ICommand command = commandFactory.CreateCreateClass(dmSolution.DefaultAssembly, className);
            command.Apply();

            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmSolution.AllClasses.Count);
            DMClass dmClass = dmSolution.AllClasses[0];
            Assert.IsFalse(dmClass.Status.IsNew);

            //---------------Execute Test ----------------------
            command.Revert();

            //---------------Test Result -----------------------
            Assert.AreEqual(0, dmSolution.AllClasses.Count);
            Assert.IsTrue(dmClass.Status.IsDeleted);
        }

        [Test]
        public void Test_Revert_ClassNameNotFound()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            string className = TestUtilsShared.GetRandomString();
            ICommandFactory commandFactory = new CommandFactory();
            ICommand command = commandFactory.CreateCreateClass(dmSolution.DefaultAssembly, className);
            command.Apply();
            DMClass dmClass = dmSolution.AllClasses[0];
            dmClass.ClassNameBO = TestUtilsShared.GetRandomString();

            //---------------Assert Precondition----------------
            Assert.IsFalse(dmClass.Status.IsNew);

            //---------------Execute Test ----------------------
            HabaneroDeveloperException exception = null;
            try
            {
                command.Revert();
            }
            catch (HabaneroDeveloperException ex)
            {
                exception = ex;
            }

            //---------------Test Result -----------------------
            Assert.IsNotNull(exception, "HabaneroDeveloperException expected");
            string expectedMessage = string.Format("Error reverting change. Class with the name '{0}' not found to remove.", className);
            Assert.AreEqual(expectedMessage, exception.Message);
        }
    }
}
